//
// Created by 吴喆 on 2020/3/24.
//

#include "CollisionListener.h"

#include "Playable.h"
#include "Bullet.h"
#include "Player.h"


void CollisionListener::PreSolve(b2Contact *contact, const b2Manifold *oldManifold) {

    b2WorldManifold worldManifold;
    contact->GetWorldManifold(&worldManifold);


    auto *a = reinterpret_cast<GameObject *>(contact->GetFixtureA()->GetBody()->GetUserData());
    auto *b = reinterpret_cast<GameObject *>(contact->GetFixtureB()->GetBody()->GetUserData());
//        std::cout << contact->GetFixtureB()->GetBody()->GetUserData() << std::endl;
//        std::cout << contact->GetManifold()->localNormal.x << "," << contact->GetManifold()->localNormal.y << std::endl;
//        std::cout << "A World Points:" << worldManifold.points[0].x << "," << worldManifold.points[0].y << std::endl;
//        std::cout << "Points:" << contact->GetManifold()->localPoint.x << "," << contact->GetManifold()->localPoint.y
//                  << std::endl;
//    }

    // 添加角色所在地板
    if ((b->objectType == OBJECT_TYPE::PLAYER || b->objectType == OBJECT_TYPE::NPC) &&
        a->objectType == OBJECT_TYPE::FLOOR) {
        auto *f = dynamic_cast<Floor *>(a);
        auto *p = dynamic_cast<Playable *>(b);

        if (p && f) {
            if (worldManifold.normal.y > 0) {
                p->floor = f;
            }
            // 是否在斜面（虽然还没用）
            p->inSlope = worldManifold.normal.x != 0 && worldManifold.normal.y != 0;

            // 是否从上方被撞击
            if (worldManifold.normal.y <= 0) {
                contact->SetEnabled(false);
                return;
            }

            if (contact->GetManifold()->localPoint.y == -0.0001 && contact->GetManifold()->localPoint.x == -0.25) {
                contact->SetEnabled(false);
                return;
            }

            if (contact->GetManifold()->localPoint.y == 0 && contact->GetManifold()->localPoint.x == 0.5 &&
                worldManifold.normal.y < 0) {
                contact->SetEnabled(false);
                return;
            }
        }
    }


}

void CollisionListener::BeginContact(b2Contact *contact) {
    auto *b = reinterpret_cast<GameObject *>(contact->GetFixtureB()->GetBody()->GetUserData());
    auto *a = reinterpret_cast<GameObject *>(contact->GetFixtureA()->GetBody()->GetUserData());
    // 每个判断ab两种情况
    {
        if (b->objectType == OBJECT_TYPE::BULLET && a->objectType == OBJECT_TYPE::NPC) {
            auto *bullet = dynamic_cast<Bullet *>(b);
            bullet->onTouched(a);
            return;
        }
        if (a->objectType == OBJECT_TYPE::BULLET && b->objectType == OBJECT_TYPE::NPC) {
            auto *bullet = dynamic_cast<Bullet *>(a);
            bullet->onTouched(b);
            return;
        }
    }
    {
        if (b->objectType == OBJECT_TYPE::PLAYER && a->objectType == OBJECT_TYPE::NPC) {
            auto *p = dynamic_cast<Player *>(b);
            p->beAtked(a);
            return;
        }
        if (a->objectType == OBJECT_TYPE::PLAYER && b->objectType == OBJECT_TYPE::NPC) {
            auto *p = dynamic_cast<Player *>(a);
            p->beAtked(b);
            return;
        }
    }
//
//    if (a->objectType == OBJECT_TYPE::BULLET && b->objectType == OBJECT_TYPE::NPC) {
//        auto *bullet = dynamic_cast<Bullet *>(a);
//        bullet->onTouched(b);
//        std::cout << "a" << std::endl;
//        return;
//    }
//    if (b->objectType == OBJECT_TYPE::PLAYER && a->objectType == OBJECT_TYPE::NPC) {
//        std::cout << "c" << std::endl;
//        return;
//    }
}

